﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Windows;
using System.Xml.Linq;


namespace TravellingEntrepreneur
{
    /// <summary>
    /// State information for BeginGetResponse async call
    /// </summary>
    public class UpdateState
    {
        public HttpWebRequest AsyncRequest { get; set; }
        public HttpWebResponse AsyncResponse { get; set; }
    }

    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            this.Items = new ObservableCollection<ItemViewModel>();
        }

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<ItemViewModel> Items { get; private set; }

        private string _sampleProperty = "Sample Runtime Property Value";
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding
        /// </summary>
        /// <returns></returns>
        public string SampleProperty
        {
            get
            {
                return _sampleProperty;
            }
            set
            {
                if (value != _sampleProperty)
                {
                    _sampleProperty = value;
                    NotifyPropertyChanged("SampleProperty");
                }
            }
        }

        public bool IsDataLoaded
        {
            get;
            private set;
        }

        ObservableCollection<RegionPrograms> newDataList = new ObservableCollection<RegionPrograms>();

        public void GetData(string state)
        {
            UriBuilder fullUri = new UriBuilder("http://green.sba.gov/ek/api/"+state+"/xml");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fullUri.Uri);
            UpdateState updateState = new UpdateState();
            updateState.AsyncRequest = request;
            request.BeginGetResponse(new AsyncCallback(HandlerDataResponse), updateState);
        }

        /// <summary>
        /// Handle the information returned from the async request
        /// </summary>
        /// <param name="asyncResult"></param>
        private void HandlerDataResponse(IAsyncResult asyncResult)
        {
            UpdateState updateState = (UpdateState)asyncResult.AsyncState;
            HttpWebRequest forecastRequest = (HttpWebRequest)updateState.AsyncRequest;
            updateState.AsyncResponse = (HttpWebResponse)forecastRequest.EndGetResponse(asyncResult);

            Stream streamResult = null;
            RegionPrograms newProgram = default(RegionPrograms);
            try
            {
                streamResult = updateState.AsyncResponse.GetResponseStream();
                XElement xmlData = XElement.Load(streamResult);
                foreach (XElement curElement in xmlData.Elements("ek"))
                {
                    try
                    {
                        string state = Convert.ToString(curElement.Element("state").Value);
                        string agency = Convert.ToString(curElement.Element("agency").Value);
                        string description = Convert.ToString(curElement.Element("description").Value);

                        newProgram = new RegionPrograms();
                        newProgram.State = state;
                        newProgram.Agency = agency;
                        newProgram.Description = description;
                        newDataList.Add(newProgram);

                    }
                    catch (FormatException)
                    {
                    }
                }
            }
            catch (FormatException)
            {
                newProgram = new RegionPrograms();
                newProgram.State = "Error";
                newProgram.Agency = "Data was not loaded";
                newProgram.Description = "Something went wrong";
                newDataList.Add(newProgram);
            }

            LoadDataFromList(newDataList);
        }

        public void LoadDataFromList(ObservableCollection<RegionPrograms> dataList)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                foreach (RegionPrograms pars in newDataList)
                {
                    this.Items.Add(
                        new ItemViewModel()
                        {
                            LineOne = pars.State,
                            LineTwo = pars.Agency,
                            LineThree = pars.Description
                        });
                }

                this.IsDataLoaded = true;
            });
        }

        public void ClearData()
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                this.Items.Clear();
                IsDataLoaded = false;
            });
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}